# -*- coding: cp936 -*-
import socket 
import threading, thread
import struct, ctypes
import maya.OpenMaya as m1
from PySide.QtGui import *

VCAM_NAME                        = "vcam"
VCAM                             = None

# Pos(x,y,z) + Rotation(x,y,z,w) = 7 * sizeof(float)
# buffer_size                    = 7 * ctypes.sizeof(ctypes.c_float)
FMT                              = struct.Struct("=7f")
BUFFER_SIZE                      = FMT.size
STRING_BUFFER                    = ctypes.create_string_buffer(BUFFER_SIZE)

def obtainVCamObject(cam_name):
    iter = m1.MItDag(m1.MItDag.kBreadthFirst, m1.MFn.kCamera)
    while not iter.isDone():
        obj = iter.item()
        fn = m1.MFnDagNode(obj)
        for i in range(fn.parentCount()):
            p = m1.MFnTransform(fn.parent(i))
            if p and (p.name() == cam_name):
                return p
        
        iter.next()
    else:
        return None


def processStringBuffer():
    global VCAM
    if not VCAM:
        VCAM = obtainVCamObject(VCAM_NAME) # m1.MFnTransform
        if not VCAM:
            print VCAM_NAME,'IS NOT EXIST'
            return False

    px,py,pz,rx,ry,rz,rw = FMT.unpack_from(STRING_BUFFER, 0)
    VCAM.setTranslation(m1.MVector(-px,py,-pz)/10, m1.MSpace.kObject) # MM(motive) -> CM(maya)
    VCAM.setRotation(m1.MQuaternion(rx,ry,rz,rw), m1.MSpace.kObject)
    return True
    
def vcam_server():
    address           = ('', 8877)
    s                 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(address)

    while True:
        nbytes, addr  = s.recvfrom_into(STRING_BUFFER, BUFFER_SIZE)
        if not nbytes == BUFFER_SIZE:
            print "client sent invalid data."
            break
        #print "received from", addr
        if not processStringBuffer():
            break
        
    s.close()


    
if __name__ == "__main__":
    vcam_thread = threading.Thread(target=vcam_server)
    vcam_thread.start()

    while vcam_thread.is_alive():
        #print 'is alive'
        QCoreApplication.processEvents()
